package com.mjh.dao;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.log4j.Logger;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopScoreDocCollector;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import com.mjh.bean.Article;
import com.mjh.bean.ArticleDetail;
import com.mjh.comm.Constant;
import com.mjh.comm.page.Pager;
import com.mjh.util.HtmlUtil;

public class ArticleSearchDAO {

	private static final String INDEX_DIR = Constant.SERVLET_CONTEXT + "WEB-INF/index";
	
	private static final String FIELD_ID = "id";
	private static final String FIELD_TITLE = "title";;
	private static final String FIELD_CONTENT = "content";
	
	private static Logger log = Logger.getLogger(ArticleSearchDAO.class);
	
	private Document articleToDocument(Article article){
		StringBuilder sb = new StringBuilder();
		for(ArticleDetail detail : article.getDetailsPage().getPageData()){
			sb.append(HtmlUtil.filterHtml(detail.getContent()));
		}
		Document doc = new Document();
		doc.add(new Field(FIELD_ID, String.valueOf(article.getId()), Field.Store.YES, Field.Index.NOT_ANALYZED));
		doc.add(new Field(FIELD_TITLE, article.getTitle(), Field.Store.NO, Field.Index.ANALYZED));
		doc.add(new Field(FIELD_CONTENT, sb.toString(), Field.Store.NO, Field.Index.ANALYZED));
		return doc;
	}
	
	public void addIndex(List<Article> articleList, boolean isCreate) throws Exception{
		log.info("添加lucene索引，数量：" + articleList.size() + "  创建索引? " + isCreate);
		long start = System.currentTimeMillis();
		IndexWriter writer = new IndexWriter(FSDirectory.open(new File(INDEX_DIR)), new SmartChineseAnalyzer(Version.LUCENE_30), isCreate, IndexWriter.MaxFieldLength.LIMITED); 
		for(Article article : articleList){
			writer.addDocument(articleToDocument(article));
		}
		writer.optimize();
		writer.close();
		log.info("添加lucene索引完成，时间：" + (System.currentTimeMillis() - start) / 1000);
	}
	
	public void updateIndex(List<Article> articleList) throws Exception{
		log.info("修改lucene索引，数量：" + articleList.size());
		long start = System.currentTimeMillis();
		IndexWriter writer = new IndexWriter(FSDirectory.open(new File(INDEX_DIR)), new SmartChineseAnalyzer(Version.LUCENE_30), false, IndexWriter.MaxFieldLength.LIMITED); 
		for(Article article : articleList){
			writer.updateDocument(new Term(FIELD_ID, String.valueOf(article.getId())), articleToDocument(article));
		}
		writer.optimize();
		writer.close();
		log.info("修改lucene索引完成，时间：" + (System.currentTimeMillis() - start) / 1000);
	}
	
	public void deleteIndex(int aritcleId) throws Exception{
		log.info("删除索引: " + aritcleId);
		long start = System.currentTimeMillis();
		IndexReader reader = IndexReader.open(FSDirectory.open(new File(INDEX_DIR)), false); 
		Term term = new Term(FIELD_ID, String.valueOf(aritcleId));
		reader.deleteDocuments(term);
		reader.close();
		log.info("删除lucene索引完成，时间：" + (System.currentTimeMillis() - start) / 1000);
	}
	
	public boolean isIndexExist() throws Exception{
		return IndexReader.indexExists(FSDirectory.open(new File(INDEX_DIR)));
	}
	
	public List<Integer> searchIndex(String keyword, Pager<Article> page) throws Exception{
		log.info("搜索关键字：" + keyword);
		List<Integer> articleIds = new ArrayList<Integer>();
		IndexReader reader = IndexReader.open(FSDirectory.open(new File(INDEX_DIR)), true); // only searching, so read-only=true
		IndexSearcher searcher = new IndexSearcher(reader);
	    Analyzer analyzer = new SmartChineseAnalyzer(Version.LUCENE_30);
	    QueryParser parser = new MultiFieldQueryParser(Version.LUCENE_30, new String[]{FIELD_TITLE,FIELD_CONTENT}, analyzer);
	    Query query = parser.parse(keyword);
	    //默认只取前1000条
	    TopScoreDocCollector collector = TopScoreDocCollector.create(1000, false);
	    //暂时按默认的相关度来排序
	    searcher.search(query, collector);
	    page.setTotalNum(collector.getTotalHits());
	    ScoreDoc[] hits = collector.topDocs(page.getStartNo(), page.getPageSize()).scoreDocs;
	    Document doc = null;
	    for(ScoreDoc scoreDoc : hits){
	    	doc = searcher.doc(scoreDoc.doc);
	    	articleIds.add(NumberUtils.toInt(doc.get(FIELD_ID)));;     
	    }
	    return articleIds;
	}
}
